package net.siufung.boot.swagger.support;

import cn.hutool.core.collection.CollectionUtil;
import net.siufung.boot.swagger.entity.DocketApiDto;
import net.siufung.boot.swagger.properties.SwaggerProperties;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 陈建峰
 * @since 2022/4/1 1:36 下午
 */
public class SpringfoxSupport {

    /**
     * 创建Rest接口
     * @param apiInfo apiInfo
     * @param swaggerProperties swaggerProperties
     * @param docketApiDto docketApiDto
     * @return
     */
    public static Docket createRestApi(
            ApiInfo apiInfo, SwaggerProperties swaggerProperties,
            DocketApiDto docketApiDto) {
        return new Docket(DocumentationType.OAS_30).pathMapping("/")
                // 定义是否开启swagger，false为关闭，可以通过变量控制
                .enable(swaggerProperties.isEnable())
                // 将api的元信息设置为包含在json ResourceListing响应中。
                .apiInfo(apiInfo)
                .groupName(docketApiDto.getGroupName())
                // 接口调试地址
                //.host(swaggerProperties.getTryHost())
                // 选择哪些接口作为swagger的doc发布
                .select()
                .apis(RequestHandlerSelectors.basePackage(docketApiDto.getBasePackage()))
                .paths(PathSelectors.any())
                .build()
                // 支持的通讯协议集合
                .protocols(CollectionUtil.newLinkedHashSet("https", "http"))
                .securitySchemes(SpringfoxSupport.securitySchemes())
                // 授权信息全局应用
                .securityContexts(SpringfoxSupport.securityContexts());
    }


    private static List<SecurityContext> securityContexts() {
        List<SecurityContext> securityContexts = new ArrayList<>();
        securityContexts.add(SecurityContext.builder()
                .securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex("/.*")).build());
        return securityContexts;
    }

    /**
     * swagger2 认证的安全上下文
     */
    private static List<SecurityScheme> securitySchemes() {
        List<SecurityScheme> securitySchemes = new ArrayList<>();
        securitySchemes.add(new ApiKey("Authorization", "Authorization", "header"));
        return securitySchemes;
    }

    private static List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        List<SecurityReference> securityReferences = new ArrayList<>();
        securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
        return securityReferences;
    }

}
